/** ****************************************************************************
@addtogroup RC_TX
@{
*******************************************************************************/

#include "rc_codec.h"
#include "rc_tx.h"


std_err_t rctx_init(driver_rctx_t* dev) {
	if(!dev || !dev->enable || !dev->emit) { return STD_ERR_INVALID_ARG; }
	dev->enable(false, 0, 0);
	return STD_ERR_OK;
}

std_err_t rctx_send_sync(driver_rctx_t* dev, RcCodeType codeType, const void *code, uint freq, uint8_t duty, int repeatTimes) {
	if(!dev || !code) { return STD_ERR_INVALID_ARG; }

	// 设置初始状态
	dev->codeType = codeType; 
	dev->code = code; 
	dev->idx = 0;
	dev->repeatTimes = repeatTimes;
	
	// 禁止中断
	OSCritical css;
	osCriticalEnter(css); //{{{	
	// 底层驱动使能
	dev->enable(true, freq, duty);
	
	while(true) {
		// 取得当前要发送的脉冲宽度(0表示结束)
		uint16_t pulse = rc_code_get(dev->codeType, dev->code, dev->idx);
		if(pulse == 0) {
			if(dev->repeatTimes == 0) {
				// 最后一次的最后一个脉冲发送完毕，发送结束
				dev->enable(false, 0, 0);
				dev->code = NULL;
				break;
			} else {
				// 本次的最后一个脉冲发送完毕，准备下一次发送
				dev->repeatTimes--; dev->idx = 0;
				pulse = rc_code_get(dev->codeType, dev->code, dev->idx);
			}
		}

		// 开始发射电平信号(偶数为低电平，奇数为高电平)	，低电平发射，高电平静默
		uint8_t level = dev->idx & 0x01;
		dev->emit(!level, 0);
		osDelayUs(pulse);

		// 下一个
		dev->idx++;
	}
	
	// 底层驱动关闭
	dev->enable(false, 0, 0);	
	// 开启中断
	osCriticalLeave(css); //}}}
	
	return STD_ERR_OK;
}

std_err_t rctx_send_async(driver_rctx_t* dev, RcCodeType codeType, const void *code, uint freq, uint8_t duty, int repeatTimes) {
	if(!dev || !code) { return STD_ERR_INVALID_ARG; }

	// 设置初始状态
	dev->codeType = codeType; 
	dev->code = code; 
	dev->idx = 0;
	dev->repeatTimes = repeatTimes;
	
	// 底层驱动使能
	dev->enable(true, freq, duty);

	// 手动触发一次中断，以便开始发送第一个脉冲
    rctx_irqHandler(dev);

	// 后面的事交给中断处理函数 rctx_irqHandler() 继续完成
	// 注意：但是现在还不能返回，必须等待发射完成才能返回！因为code是一个局部变量，返回之后就非法了！
	while(dev->code) { osFeedWatchdog(); };
	
	return STD_ERR_OK;
}

void rctx_irqHandler(driver_rctx_t* dev) {
	// 没有要发送的数据，关闭并返回
	if(!dev->code) { dev->enable(false, 0, 0); return; }

	// 取得当前要发送的脉冲宽度(0表示结束)
	uint16_t pulse = rc_code_get(dev->codeType, dev->code, dev->idx);
	if(pulse == 0) {
		if(dev->repeatTimes == 0) {
			// 最后一次的最后一个脉冲发送完毕，发送结束
            dev->enable(false, 0, 0);
			dev->code = NULL;
			return;
		} else {
			// 本次的最后一个脉冲发送完毕，准备下一次发送
			dev->repeatTimes--; dev->idx = 0;
			pulse = rc_code_get(dev->codeType, dev->code, dev->idx);
		}
	}

	// 开始发射电平信号(偶数为低电平，奇数为高电平)	，低电平发射，高电平静默
	uint8_t level = dev->idx & 0x01;
	dev->emit(!level, pulse);

	// 下一个
	dev->idx++;
}


/// @}
